home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / Obrn-A_1.6_lib.lha / oberon-a / source3.lha / source / Library / Sets.mod < prev    next >
Text File  |  1995-06-29  |  11KB  |  473 lines

  1. (*************************************************************************
  2.  
  3.      $RCSfile: Sets.mod $
  4.   Description: A general module for handling sets of all sizes.
  5.  
  6.    Created by: fjc (Frank Copeland)
  7.     $Revision: 1.4 $
  8.       $Author: fjc $
  9.         $Date: 1995/06/04 23:22:41 $
  10.  
  11.   Copyright © 1994-1995, Frank Copeland.
  12.   This file is part of the Oberon-A Library.
  13.   See Oberon-A.doc for conditions of use and distribution.
  14.  
  15. *************************************************************************)
  16.  
  17. <* STANDARD- *>
  18.  
  19. MODULE Sets;
  20.  
  21. (**
  22. ** This module serves a number of purposes. It first of all attempts to
  23. ** provide a portable interface to the non-standard set variants used by
  24. ** a number of Oberon compilers. It also implements a Set class to handle
  25. ** sets of any arbitrary size. This is based on an example in Mössenböck's
  26. ** "Object-oriented Programming in Oberon-2". Finally, it provides an
  27. ** extension of the Set class that emulates Modula-2's SET OF CHAR.
  28. *)
  29.  
  30. (**
  31. ** Portable set variants.
  32. **
  33. ** The following types are aliases intended to provide a portable
  34. ** interface to the non-standard set types provided by many Oberon
  35. ** compilers.
  36. **
  37. ** The problem is this: Oberon defines only one set type, which is
  38. ** typically implemented as the "natural" word size of the host machine.
  39. ** However, many compilers provide set variants in different sizes. The
  40. ** logical type hierarchy is LONGSET <- SET <- SHORTSET, with LONGSET
  41. ** being 32 bits, SET 16 bits and SHORTSET 8 bits. Unfortunately, the
  42. ** Oakwood Report and the defacto standard OP2 compiler do not provide
  43. ** for variants, and use 32 bits for SET types. Oberon-A follows this
  44. ** standard by making SET 32 bits, but it also provides 16 and 8 bit
  45. ** variants, which makes it incompatible with other compilers that use the
  46. ** LONGSET/SET/SHORTSET system.
  47. **
  48. ** The objective of this module is to provide a portable interface to
  49. ** such set variants that can be used with different compilers. The
  50. ** implementation will vary depending on the compiler being used, and if a
  51. ** particular sized set is not provided it must be emulated.
  52. *)
  53.  
  54. IMPORT SYSTEM;
  55.  
  56. TYPE
  57.  
  58.   SET8  *= SYSTEM.BYTESET;
  59.   SET16 *= SYSTEM.WORDSET;
  60.   SET32 *= SET;
  61.  
  62.  
  63. (**
  64. ** The Set type defines a class that can be used to create and manage sets
  65. ** of any arbitrary size. It is based directly on an example in chapter
  66. ** 4.3 of "Object-oriented Programming in Oberon-2".
  67. *)
  68.  
  69. CONST setSize = MAX (SET) + 1;
  70.  
  71. TYPE
  72.  
  73.   Set *= RECORD
  74.     max -: INTEGER; (* Largest element allowed *)
  75.     val : POINTER TO ARRAY OF SET;
  76.   END; (* Set *)
  77.  
  78.  
  79. (**
  80. ** The CharSet class extends the Set class to allow for sets of ASCII
  81. ** characters, emulating the SET OF CHAR type that was possible in most
  82. ** Modula-2s.
  83. *)
  84.  
  85. TYPE
  86.  
  87.   CharSet *= RECORD (Set) END;
  88.  
  89.  
  90. (**
  91. ** The following procedures implement the basic set operations:
  92. **
  93. **   - assigning the empty set : s := {}      -> Clear? (s)
  94. **   - assigning a set value   : s := s1      -> Copy? (s, s1)
  95. **   - including an element    : INCL (s, i)  -> Incl? (s, i)
  96. **   - excluding an element    : EXCL (s, i)  -> Excl? (s, i)
  97. **   - set union               : s := s1 + s2 -> s := Add? (s1, s2)
  98. **   - set difference          : s := s1 - s2 -> s := Subtract? (s1, s2)
  99. **   - set intersection        : s := s1 * s2 -> s := Intersect? (s1, s2)
  100. **   - symmetric differnece    : s := s1 / s2 -> s := SymDiff? (s1, s2)
  101. **   - set membership          : i IN s       -> In? (s, i)
  102. **
  103. ** Three versions of each procedure are provided, one for each set type.
  104. ** Most of these procedures may seem unnecessary, as they are implemented
  105. ** directly using normal set operations. However, when using a compiler
  106. ** that does not provide any or all of the set variants as extensions, the
  107. ** operations must be implemented using other types, such as SYSTEM.BYTE.
  108. ** The procedures allow code using this module to be ported to such a
  109. ** compiler without change, as the details of the implementation are
  110. ** wrapped in a procedure interface.
  111. **
  112. ** Type conversion functions are also provided:
  113. **
  114. **   - 8 bit  -> 16 bit : Long8()
  115. **   - 16 bit -> 32 bit : Long16()
  116. **   - 16 bit -> 8 bit  : Short16()
  117. **   - 32 bit -> 16 bit : Short32()
  118. *)
  119.  
  120. PROCEDURE Clear8 * ( VAR s : SET8 );
  121. BEGIN (* Clear8 *)
  122.   s := {}
  123. END Clear8;
  124.  
  125.  
  126. PROCEDURE Copy8 * ( VAR s1 : SET8; s2 : SET8 );
  127. BEGIN (* Copy8 *)
  128.   s1 := s2
  129. END Copy8;
  130.  
  131.  
  132. PROCEDURE Incl8 * ( VAR s : SET8; i : INTEGER );
  133. BEGIN (* Incl8 *)
  134.   INCL (s, i)
  135. END Incl8;
  136.  
  137.  
  138. PROCEDURE Excl8 * ( VAR s : SET8; i : INTEGER );
  139. BEGIN (* Excl8 *)
  140.   EXCL (s, i)
  141. END Excl8;
  142.  
  143.  
  144. PROCEDURE Add8 * ( s1, s2 : SET8 ) : SET8;
  145. BEGIN (* Add8 *)
  146.   RETURN s1 + s2
  147. END Add8;
  148.  
  149.  
  150. PROCEDURE Subtract8 * ( s1, s2 : SET8 ) : SET8;
  151. BEGIN (* Subtract8 *)
  152.   RETURN s1 - s2
  153. END Subtract8;
  154.  
  155.  
  156. PROCEDURE Intersect8 * ( s1, s2 : SET8 ) : SET8;
  157. BEGIN (* Intersect8 *)
  158.   RETURN s1 * s2
  159. END Intersect8;
  160.  
  161.  
  162. PROCEDURE SymDiff8 * ( s1, s2 : SET8 ) : SET8;
  163. BEGIN (* SymDiff8 *)
  164.   RETURN s1 / s2
  165. END SymDiff8;
  166.  
  167.  
  168. PROCEDURE In8 * ( s1 : SET8; i : INTEGER ) : BOOLEAN;
  169. BEGIN (* In8 *)
  170.   RETURN i IN s1
  171. END In8;
  172.  
  173.  
  174. PROCEDURE Clear16 * ( VAR s : SET16 );
  175. BEGIN (* Clear16 *)
  176.   s := {}
  177. END Clear16;
  178.  
  179.  
  180. PROCEDURE Copy16 * ( VAR s1 : SET16; s2 : SET16 );
  181. BEGIN (* Copy16 *)
  182.   s1 := s2
  183. END Copy16;
  184.  
  185.  
  186. PROCEDURE Incl16 * ( VAR s : SET16; i : INTEGER );
  187. BEGIN (* Incl16 *)
  188.   INCL (s, i)
  189. END Incl16;
  190.  
  191.  
  192. PROCEDURE Excl16 * ( VAR s : SET16; i : INTEGER );
  193. BEGIN (* Excl16 *)
  194.   EXCL (s, i)
  195. END Excl16;
  196.  
  197.  
  198. PROCEDURE Add16 * ( s1, s2 : SET16 ) : SET16;
  199. BEGIN (* Add16 *)
  200.   RETURN s1 + s2
  201. END Add16;
  202.  
  203.  
  204. PROCEDURE Subtract16 * ( s1, s2 : SET16 ) : SET16;
  205. BEGIN (* Subtract16 *)
  206.   RETURN s1 - s2
  207. END Subtract16;
  208.  
  209.  
  210. PROCEDURE Intersect16 * ( s1, s2 : SET16 ) : SET16;
  211. BEGIN (* Intersect16 *)
  212.   RETURN s1 * s2
  213. END Intersect16;
  214.  
  215.  
  216. PROCEDURE SymDiff16 * ( s1, s2 : SET16 ) : SET16;
  217. BEGIN (* SymDiff16 *)
  218.   RETURN s1 / s2
  219. END SymDiff16;
  220.  
  221.  
  222. PROCEDURE In16 * ( s1 : SET16; i : INTEGER ) : BOOLEAN;
  223. BEGIN (* In16 *)
  224.   RETURN i IN s1
  225. END In16;
  226.  
  227.  
  228. PROCEDURE Clear32 * ( VAR s : SET32 );
  229. BEGIN (* Clear32 *)
  230.   s := {}
  231. END Clear32;
  232.  
  233.  
  234. PROCEDURE Copy32 * ( VAR s1 : SET32; s2 : SET32 );
  235. BEGIN (* Copy32 *)
  236.   s1 := s2
  237. END Copy32;
  238.  
  239.  
  240. PROCEDURE Incl32 * ( VAR s : SET32; i : INTEGER );
  241. BEGIN (* Incl32 *)
  242.   INCL (s, i)
  243. END Incl32;
  244.  
  245.  
  246. PROCEDURE Excl32 * ( VAR s : SET32; i : INTEGER );
  247. BEGIN (* Excl32 *)
  248.   EXCL (s, i)
  249. END Excl32;
  250.  
  251.  
  252. PROCEDURE Add32 * ( s1, s2 : SET32 ) : SET32;
  253. BEGIN (* Add32 *)
  254.   RETURN s1 + s2
  255. END Add32;
  256.  
  257.  
  258. PROCEDURE Subtract32 * ( s1, s2 : SET32 ) : SET32;
  259. BEGIN (* Subtract32 *)
  260.   RETURN s1 - s2
  261. END Subtract32;
  262.  
  263.  
  264. PROCEDURE Intersect32 * ( s1, s2 : SET32 ) : SET32;
  265. BEGIN (* Intersect32 *)
  266.   RETURN s1 * s2
  267. END Intersect32;
  268.  
  269.  
  270. PROCEDURE SymDiff32 * ( s1, s2 : SET32 ) : SET32;
  271. BEGIN (* SymDiff32 *)
  272.   RETURN s1 / s2
  273. END SymDiff32;
  274.  
  275.  
  276. PROCEDURE In32 * ( s1 : SET32; i : INTEGER ) : BOOLEAN;
  277. BEGIN (* In32 *)
  278.   RETURN i IN s1
  279. END In32;
  280.  
  281.  
  282. PROCEDURE Long8 * ( s : SET8 ) : SET16;
  283. BEGIN (* Long8 *)
  284.   RETURN LONG (s)
  285. END Long8;
  286.  
  287.  
  288. PROCEDURE Long16 * ( s : SET16 ) : SET32;
  289. BEGIN (* Long16 *)
  290.   RETURN LONG (s)
  291. END Long16;
  292.  
  293.  
  294. PROCEDURE Short16 * ( s : SET16 ) : SET8;
  295. BEGIN (* Short16 *)
  296.   RETURN SHORT (s)
  297. END Short16;
  298.  
  299.  
  300. PROCEDURE Short32 * ( s : SET32 ) : SET16;
  301. BEGIN (* Short32 *)
  302.   RETURN SHORT (s)
  303. END Short32;
  304.  
  305.  
  306. <*$IndexChk-*>
  307.  
  308. PROCEDURE (VAR s : Set) Init * ( max : INTEGER );
  309. BEGIN (* Init *)
  310.   s.max := max;
  311.   NEW (s.val, (max + setSize) DIV setSize)
  312. END Init;
  313.  
  314.  
  315. PROCEDURE (VAR s : Set) CopyTo * ( VAR s1 : Set );
  316.   VAR i : INTEGER;
  317. BEGIN (* CopyTo *)
  318.   s1.Init (s.max);
  319.   FOR i := 0 TO s.max DIV setSize DO s1.val [i] := s.val [i] END
  320. END CopyTo;
  321.  
  322.  
  323. PROCEDURE (VAR s : Set) Clear *;
  324.   VAR i : INTEGER;
  325. BEGIN (* Clear *)
  326.   FOR i := 0 TO s.max DIV setSize DO s.val [i] := {} END
  327. END Clear;
  328.  
  329.  
  330. PROCEDURE (VAR s : Set) Incl * ( x : INTEGER );
  331. BEGIN (* Incl *)
  332.   IF (x > 0) & (x <= s.max) THEN
  333.     INCL (s.val [x DIV setSize], x MOD setSize)
  334.   END
  335. END Incl;
  336.  
  337.  
  338. PROCEDURE (VAR s : Set) InclRange * ( x, y : INTEGER );
  339.   VAR i : INTEGER;
  340. BEGIN (* InclRange *)
  341.   IF y < x THEN i := x; x := y; y := i END;
  342.   IF x < 0 THEN x := 0 END; IF y > s.max THEN y := s.max END;
  343.   FOR i := x TO y DO
  344.     INCL (s.val [i DIV setSize], i MOD setSize)
  345.   END
  346. END InclRange;
  347.  
  348.  
  349. PROCEDURE (VAR s : Set) Excl * ( x : INTEGER );
  350. BEGIN (* Excl *)
  351.   IF (x > 0) & (x <= s.max) THEN
  352.     EXCL (s.val [x DIV setSize], x MOD setSize)
  353.   END
  354. END Excl;
  355.  
  356.  
  357. PROCEDURE (VAR s : Set) ExclRange * ( x, y : INTEGER );
  358.   VAR i : INTEGER;
  359. BEGIN (* ExclRange *)
  360.   IF y < x THEN i := x; x := y; y := i END;
  361.   IF x < 0 THEN x := 0 END; IF y > s.max THEN y := s.max END;
  362.   FOR i := x TO y DO
  363.     EXCL (s.val [i DIV setSize], i MOD setSize)
  364.   END
  365. END ExclRange;
  366.  
  367.  
  368. PROCEDURE (VAR s : Set) Contains * ( x : INTEGER ) : BOOLEAN;
  369. BEGIN (* Contains *)
  370.   RETURN (x > 0) & (x <= s.max)
  371.          & (x MOD setSize IN s.val [x DIV setSize])
  372. END Contains;
  373.  
  374.  
  375. PROCEDURE (VAR s : Set) Add * ( VAR s1 : Set );
  376.   VAR i, max : INTEGER;
  377. BEGIN (* Add *)
  378.   max := s.max; IF s1.max < max THEN max := s1.max END;
  379.   FOR i := 0 TO max DIV setSize DO
  380.     s.val [i] := s.val [i] + s1.val [i]
  381.   END
  382. END Add;
  383.  
  384.  
  385. PROCEDURE (VAR s : Set) Subtract * ( VAR s1 : Set );
  386.   VAR i, max : INTEGER;
  387. BEGIN (* Subtract *)
  388.   max := s.max; IF s1.max < max THEN max := s1.max END;
  389.   FOR i := 0 TO max DIV setSize DO
  390.     s.val [i] := s.val [i] - s1.val [i]
  391.   END
  392. END Subtract;
  393.  
  394.  
  395. PROCEDURE (VAR s : Set) Intersect * ( VAR s1 : Set );
  396.   VAR i, max : INTEGER;
  397. BEGIN (* Intersect *)
  398.   max := s.max; IF s1.max < max THEN max := s1.max END;
  399.   FOR i := 0 TO max DIV setSize DO
  400.     s.val [i] := s.val [i] * s1.val [i]
  401.   END
  402. END Intersect;
  403.  
  404.  
  405. PROCEDURE (VAR s : Set) SymDiff * ( VAR s1 : Set );
  406.   VAR i, max : INTEGER;
  407. BEGIN (* SymDiff *)
  408.   max := s.max; IF s1.max < max THEN max := s1.max END;
  409.   FOR i := 0 TO max DIV setSize DO
  410.     s.val [i] := s.val [i] / s1.val [i]
  411.   END
  412. END SymDiff;
  413.  
  414.  
  415. PROCEDURE (VAR s : CharSet) Init * ( max : INTEGER );
  416. BEGIN (* Init *)
  417.   s.Init^ (ORD (MAX (CHAR)))
  418. END Init;
  419.  
  420.  
  421. PROCEDURE (VAR s : CharSet) InclCh * ( ch : CHAR );
  422. BEGIN (* InclCh *)
  423.   s.Incl^ (ORD (ch))
  424. END InclCh;
  425.  
  426.  
  427. PROCEDURE (VAR s : CharSet) InclChRange * ( ch1, ch2 : CHAR );
  428. BEGIN (* InclChRange *)
  429.   s.InclRange^ (ORD (ch1), ORD (ch2))
  430. END InclChRange;
  431.  
  432.  
  433. PROCEDURE (VAR s : CharSet) InclStr * ( str : ARRAY OF CHAR );
  434.   VAR i : INTEGER; ch : CHAR;
  435. BEGIN (* InclStr *)
  436.   i := 0;
  437.   LOOP
  438.     ch := str [0]; IF ch = 0X THEN EXIT END;
  439.     s.Incl^ (ORD (ch)); INC (i)
  440.   END
  441. END InclStr;
  442.  
  443.  
  444. PROCEDURE (VAR s : CharSet) ExclCh * ( ch : CHAR );
  445. BEGIN (* ExclCh *)
  446.   s.Excl^ (ORD (ch))
  447. END ExclCh;
  448.  
  449.  
  450. PROCEDURE (VAR s : CharSet) ExclChRange * ( ch1, ch2 : CHAR );
  451. BEGIN (* ExclChRange *)
  452.   s.ExclRange^ (ORD (ch1), ORD (ch2))
  453. END ExclChRange;
  454.  
  455.  
  456. PROCEDURE (VAR s : CharSet) ExclStr * ( str : ARRAY OF CHAR );
  457.   VAR i : INTEGER; ch : CHAR;
  458. BEGIN (* ExclStr *)
  459.   i := 0;
  460.   LOOP
  461.     ch := str [0]; IF ch = 0X THEN EXIT END;
  462.     s.Excl^ (ORD (ch)); INC (i)
  463.   END
  464. END ExclStr;
  465.  
  466.  
  467. PROCEDURE (VAR s : CharSet) ContainsCh * ( ch : CHAR ) : BOOLEAN;
  468. BEGIN (* ContainsCh *)
  469.   RETURN s.Contains^ (ORD (ch))
  470. END ContainsCh;
  471.  
  472. END Sets.
  473.